package com.zzq.my.jetpacks.util

import android.os.Parcelable
import com.blankj.utilcode.util.PathUtils
import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import java.util.*

/*
  * ================================================
  * 描述：基于腾讯mmkv 封装的一个高性能存储工具类
  * 作者：zhuangzeqin
  * 时间: 2022/2/11-15:46
  * 邮箱：zzq@eeepay.cn
  * 备注:
  * ----------------------------------------------------------------
  * You never know what you can do until you try !
  *      _              _           _     _   ____  _             _ _
  *     / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
  *    / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
  *   / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
  *  /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
  *
  * 签名：最痛苦的事不是我失败了，而是我本可以.--zzq
  * ----------------------------------------------------------------
  * ================================================
  */
object MMKVUtils {
     val kv: MMKV by lazy {
        MMKV.defaultMMKV()
        //如果不同业务需要区别存储，也可以单独创建自己的实例：
//        MMKV.mmkvWithID("MMKVUtils")
        //如果业务需要多进程访问，那么在初始化的时候加上标志位 MMKV.MULTI_PROCESS_MODE：
//        val mmkv = MMKV.mmkvWithID("InterProcessKV", MMKV.MULTI_PROCESS_MODE)
    }

    init {
        // 1、可以修改目录的初始化 目录：/data/data/包名/files/mmkv
        // val path = filesDir.absolutePath + "/mmkv"
        // MMKV.initialize(path)
        //2、普通初始化 目录：/data/data/包名/files
//        MMKV.initialize(this)
        // 1和2使用一个就可以了
        val rootDir = MMKV.initialize(PathUtils.getInternalAppFilesPath())
        Logger.d(rootDir)
    }

    /**
     * 支持   boolean、int、long、float、double、byte[]。
     *  支持  String、Set<String>、任何实现了Parcelable的类型。
     */
    fun put(key: String, value: Any?): Boolean {
        value ?: return false
        return when (value) {
            is Boolean -> kv.encode(key, value)
            is ByteArray -> kv.encode(key, value)
            is Float -> kv.encode(key, value)
            is Int -> kv.encode(key, value)
            is Double->kv.encode(key,value)
            is Long -> kv.encode(key, value)
            is String -> kv.encode(key, value)
//            is Parcelable -> kv.encode(key, value)//任何实现了Parcelable的类型。
//            is Set<*>-> kv.encode(key, value as MutableSet<String>)
            else -> false
        }
    }

    /**
     * 这里使用安卓自带的Parcelable序列化，它比java支持的Serializer序列化性能好些
     */
    fun <T : Parcelable> put(key: String, t: T?): Boolean {
        if (t == null) {
            return false
        }
        return kv.encode(key, t)
    }

    fun put(key: String, sets: Set<String>?): Boolean {
        if (sets == null) {
            return false
        }
        return kv.encode(key, sets)
    }

    fun getBoolean(key: String, defValue: Boolean? = false) = kv.decodeBool(key, defValue!!)

    fun getByteArray(key: String, defValue: ByteArray? = null) = kv.decodeBytes(key, defValue)

    fun getFloat(key: String, defValue: Float? = 0F) = kv.decodeFloat(key, defValue!!)

    fun getInt(key: String, defValue: Int? = 0) = kv.decodeInt(key, defValue!!)

    fun getDouble(key: String, defValue: Double? = 0.00)= kv.decodeDouble(key,defValue!!)

    fun getLong(key: String, defValue: Long? = 0L) = kv.decodeLong(key, defValue!!)

    fun getString(key: String, defValue: String? = "") = kv.decodeString(key, defValue)


    /**
     * MMKVUtils.getParcelable<Class>("")
     */
    inline fun <reified T : Parcelable> getParcelable(key: String): T? {
        return kv.decodeParcelable(key, T::class.java)
    }

    fun getStringSet(key: String): Set<String>? {
        return kv.decodeStringSet(key, Collections.emptySet())
    }

    /**
     * 移除某个key对
     */
    fun removeKey(key: String) = kv.removeValueForKey(key)

    /**
     *  移除一组key
     *  arrayOf("key1", "key2")
     */
    fun removeKeyArray(keys: Array<String>)=kv.removeValuesForKeys(keys)

    /**
     *  清除所有key
     */
    fun clearAll()=kv.clearAll()
}